GNU gcc compiler

C 기본적인 파일 구조

├── include

│   └── headerEx.h

└── src

    ├── main.c

    ├── srcEx1.c

    └── srcEx2.c

gcc [options] [src] -o [ouput]

-I<include path>    ; include할 파일의 위치 지정(띄어쓰기 X)
1. obj 파일 합쳐서 프로그램 생성
gcc -c -Iinclude src/srcEx1.c -o obj/srcEx1.o
gcc -c -Iinclude src/srcEx2.c -o obj/srcEx2.o
gcc -Iinclude src/main.c obj/srcEx1.o obj/srcEx2.o -o bin/main

대규모 프로그램에서는 라이브러리로 만들어서 관리하는 것이 좋음
2. Library로 만들어서 프로그램 생성
.a: static library: object 파일의 모임
.so: shared library

readelf -s <object file> 을 이용해서 해당 파일의 심볼 확인 가능

--- 정적 라이브러리 링킹 ---
ar rcs <library name> <object files ... >
gcc -L<라이브러리 위치> src.c -l<라이브러리 이름(파일명 X)> -o <output file name>
ar [option]descriptionexamples
r아카이브에 새로운 오브젝트 추가
오래된 오브젝트는 새 오브젝트로 교체
ar r [lib] [object]
c아카이브가 존재하지 않으면 생성ar rcs [lib] [object]
t아카이브에 있는 파일 리스트 출력ar t [library]
x아카이브에서 오브젝트 파일 추출ar x [library]
s아카이브에 오브젝트파일 idx 넣기
이 index는 library에서 lookup-symbol로 컴파일러에서 사용됨
ar rcs [lib] [object]
gcc -c -Iinclude src/srcEx1.c -o obj/srcEx1.o
gcc -c -Iinclude src/srcEx2.c -o obj/srcEx2.o
ar rcs include/libEx.a obj/srcEx1.o obj/srcEx2.o
(라이브러리 이름은 lib<name>.a 로 함)
gcc -Linclude main.c -lEx -o main

default로 빌드할 때, 동적 링커를 사용한다.
gcc -static 옵션을 이용해서 명시적으로 static으로 링크

--- 공유 라이브러리 링킹 ---
프로그램 시작할 때 dynamic linking되어 적재됨(프로그램과 별도로 존재)
(라이브러리 이름 lib<name>.so로 함)
정적 라이브러리는 오브젝트 파일 생성을 일반적으로 수행하였지만, 동적 링킹을 위해서는 -fPIC 옵션을 이용해서 오브젝트 파일 생성
gcc -fPIC -c srcEx1.c    # srcEx1.o 생성
gcc -fPIC -c srcEx2.c    # srcEx2.o 생성
(-fPIC: Position Independent Code로 컴파일)
gcc -shared -Wl , -soname lib[name].so.1 -o lib[name].so.1.0 src1Ex.o src2Ex.o
gcc -L<라이브러리 위치> src.c -l<라이브러리 이름(파일명 X)> -o <output file name>


CFLAGSdescription
-sharedcompiler에게 executable한 object에게 link를 걸어 줄 수 있는 shared library를 만든다고 set 하는 flag

LDFLAGS                      description
-Wl,[options]-Wl,은 링커(collect2)에게 gcc 거치지 않고 바로 전해주는 옵션. 뒤에 [options]에 링크 옵션을 넣어준다.
-Wl,-soname,lib[name].so.1생성하려는 shared library의 soname을 뒤에 지어준다.
soname에는 major 버전만 명시

dynamic link되어 있을 경우, 실행시 shared library 위치를 찾지 못해 실패할 수 있음
환경 변수 $LD_LIBRARY_PATH를 등록해서 추가할 수 있음
0. /lib, /usr/lib, /usr/local/lib
1. 환경변수 $LD_LIBRARY_PATH
2. /etc/ld.so.conf, /etc/ld.so.conf.d/libexample.conf, /etc/ld.so.cache
3. 컴파일 할 때 부터 -Wl, -rpath, [path]로 등록해줌
ldd <binary file>    ; 응용프로그램 의존성 체크
동적 적재 라이브러리
프로그램이 시작할 때(동적 라이브러리) 적재되는 것이 아닌 다른 시기에 적재되는 라이브러리
#include <dlfcn.h>
void* dlopen(const char* filename, int flag); //flags: RTLD_LAZY | RTLD_NOW
void* dlsysm(void* handle, const char* symbol);
int dlclose(void*);
char* dlerror(void);
동적 적재를 사용했을 경우,
gcc -o <output> <input> -ldl